package com.naiterui.ehp.bp.support.config;

import java.util.List;
import java.util.Timer;

import javax.annotation.PreDestroy;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.openfeign.support.FeignHttpClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;

import com.naiterui.ehp.bp.support.interceptor.InnerClientHttpRequestInterceptor;
import com.naiterui.ehp.bp.support.utils.RestTemplateUtil;

@Configuration
public class HttpClientConfiguration {
    private final Timer connectionManagerTimer = new Timer("ApacheHttpClientConfiguration.connectionManagerTimer", true);

    private CloseableHttpClient httpClient;

    @Autowired(required = false)
    private RegistryBuilder registryBuilder;

    @Bean
    public HttpClientConnectionManager connectionManager(ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
                                                         FeignHttpClientProperties httpClientProperties) {
        final HttpClientConnectionManager connectionManager = connectionManagerFactory.newConnectionManager(
                true,
                httpClientProperties.getMaxConnections(),
                httpClientProperties.getMaxConnectionsPerRoute(),
                httpClientProperties.getTimeToLive(),
                httpClientProperties.getTimeToLiveUnit(),
                this.registryBuilder);
        return connectionManager;
    }

    @Bean
    public CloseableHttpClient httpClient(HttpClientConnectionManager httpClientConnectionManager) {
        HttpClientBuilder builder = HttpClientBuilder.create().disableCookieManagement().useSystemProperties();
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                                                          .setConnectTimeout(RestTemplateUtil.DEFAULT_CONNECT_TIMEOUT)
                                                          .setSocketTimeout(RestTemplateUtil.DEFAULT_READ_TIMEOUT)
                                                          .setConnectionRequestTimeout(RestTemplateUtil.DEFAULT_CONNECTION_REQUEST_TIME_OUT)
                                                          .build();

        this.httpClient = builder.setDefaultRequestConfig(defaultRequestConfig)
                                 .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
                                 .setConnectionManager(httpClientConnectionManager)
                                 .build();
        return this.httpClient;
    }


    @PreDestroy
    public void destroy() throws Exception {
        this.connectionManagerTimer.cancel();
        if (this.httpClient != null) {
            this.httpClient.close();
        }
    }

    /**
     * 初始化RestTemplate,并加入spring的Bean工厂，由spring统一管理,此RestTemplate是使用LoadBalanced加工过的
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = RestTemplateUtil.create();
        List<ClientHttpRequestInterceptor> list = restTemplate.getInterceptors();
        list.add(new InnerClientHttpRequestInterceptor());
        restTemplate.setInterceptors(list);
        return restTemplate;
    }

}
